/*
 * HibernateUtil.java
 *
 * Created on January 8, 2007, 4:49 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package com.ivanbiz.helper;

import com.ivanbiz.gui.MainMenu;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.jasypt.util.text.BasicTextEncryptor;

/**
 *
 * @author Ivan
 */
public class HibernateUtil extends MainMenu {

    private static final SessionFactory sessionFactory;
    private static final ThreadLocal threadSession = new ThreadLocal();
    private static final ThreadLocal threadTransaction = new ThreadLocal();


    static {
        try {
            File file = new File("config.properties");
            FileInputStream fis = new FileInputStream(file.getAbsolutePath());
            InputStreamReader reader = new InputStreamReader(fis, Charset.forName("UTF-8"));
            ResourceBundle rb = new PropertyResourceBundle(reader);
            String encryptionPassword = ")(*&^%$#@!~!&#%~*#^~(#~%$s";
            BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
            basicTextEncryptor.setPassword(encryptionPassword);
            String url = basicTextEncryptor.decrypt(rb.getString("url").trim());
            String userName = basicTextEncryptor.decrypt(rb.getString("userName").trim());
            String password = basicTextEncryptor.decrypt(rb.getString("password").trim());

            sessionFactory = (SessionFactory) new Configuration().configure("hibernate.cfg.xml").
                    setProperty("hibernate.connection.url", "jdbc:mysql://" + url).
                    setProperty("hibernate.connection.username", userName).
                    setProperty("hibernate.connection.password", password).
                    buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory failed. " + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession() {
        Session s = (Session) threadSession.get();
        try {
            if (s == null) {
                s = sessionFactory.openSession();
                threadSession.set(s);
            }
        } catch (HibernateException ex) {
            throw ex;
        }
        return s;
    }

    public static void closeSession() {
        try {
            Session s = (Session) threadSession.get();
            threadSession.set(null);
            if (s != null && s.isOpen()) {
                s.close();
            }
        } catch (HibernateException ex) {
            throw ex;
        }
    }

    public static void beginTransaction() {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            if (tx == null) {
                tx = getSession().beginTransaction();
                threadTransaction.set(tx);
            }
        } catch (HibernateException ex) {
            throw ex;
        }
    }

    public static void commitTransaction() {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
                tx.commit();
            }
            threadTransaction.set(null);
        } catch (HibernateException ex) {
            rollbackTransaction();
            throw ex;
        }
    }

    public static void rollbackTransaction() {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            threadTransaction.set(null);
            if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
                tx.rollback();
            }
        } catch (HibernateException ex) {
            throw ex;
        } finally {
            closeSession();
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
